/*
 * SPDX-FileCopyrightText: 2022-2024 Andrew Gunnerson
 * SPDX-License-Identifier: GPL-3.0-only
 */

@file:OptIn(ExperimentalUnsignedTypes::class)

package com.sanji.audio_test.format

import android.media.MediaCodecInfo
import android.media.MediaFormat
import android.media.MediaMuxer
import java.io.FileDescriptor

/**
 * AAC音频格式实现类
 * 
 * 支持M4A容器格式和AAC音频编码的格式处理器
 */
class AacFormat : Format() {
    /**
     * 格式名称，用于用户界面显示
     */
    override val name: String = "M4A/AAC"
    
    /**
     * 容器格式的MIME类型
     * 遵循RFC 6381标准中关于MP4音频的标识
     */
    override val mimeTypeContainer: String = "audio/mp4"
    
    /**
     * 音频编码的MIME类型
     * 使用Android系统定义的AAC音频MIME类型
     */
    override val mimeTypeAudio: String = MediaFormat.MIMETYPE_AUDIO_AAC
    
    /**
     * 是否支持直通模式
     * AAC格式不支持直通，需要重新编码
     */
    override val passthrough: Boolean = false
    
    /**
     * 格式参数信息
     * 定义AAC编码的比特率参数范围和默认值
     */
    override val paramInfo: FormatParamInfo = RangedParamInfo(
        RangedParamType.Bitrate,
        // 该格式没有硬性限制，所以下限采用ffmpeg推荐的HE-AAC最小比特率：24kbps/通道
        // 上限采用AAC-LC达到可听透明度所需比特率的两倍：2 * 64kbps/通道
        // 参考：https://trac.ffmpeg.org/wiki/Encode/AAC
        24_000u..128_000u,
        64_000u,
        uintArrayOf(
            24_000u,
            // 经验法则：每个通道使用64 kBit/s可实现可听透明度
            64_000u,
            128_000u,
        ),
    )
    
    /**
     * 采样率信息
     * 基于编解码器支持的采样率，推荐使用16kHz
     */
    override val sampleRateInfo: SampleRateInfo =
        SampleRateInfo.fromCodec(baseMediaFormat, 16_000u)

    /**
     * 更新媒体格式配置
     * 
     * 根据指定参数设置AAC编码的相关属性，包括编码配置文件和比特率
     * 
     * @param mediaFormat 媒体格式对象
     * @param param 指定的编码参数（比特率）
     */
    override fun updateMediaFormat(mediaFormat: MediaFormat, param: UInt) {
        mediaFormat.apply {
            // 根据比特率选择适当的AAC配置文件
            val profile = if (param >= 32_000u) {
                // 比特率>=32kbps时使用LC（低复杂度）配置文件
                MediaCodecInfo.CodecProfileLevel.AACObjectLC
            } else {
                // 比特率<32kbps时使用HE（高效率）配置文件
                MediaCodecInfo.CodecProfileLevel.AACObjectHE
            }
            // 获取声道数用于计算总比特率
            val channelCount = getInteger(MediaFormat.KEY_CHANNEL_COUNT)

            // 设置AAC配置文件
            setInteger(MediaFormat.KEY_AAC_PROFILE, profile)
            // 设置总比特率（比特率*声道数）
            setInteger(MediaFormat.KEY_BIT_RATE, param.toInt() * channelCount)
        }
    }

    /**
     * 创建容器对象
     * 
     * 为AAC音频创建MPEG-4格式的媒体复用器容器
     * 
     * @param fd 文件描述符
     * @return MediaMuxerContainer对象
     */
    override fun getContainer(fd: FileDescriptor): Container =
        MediaMuxerContainer(fd, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
}